package com.neusoft.neuiotms.dcam.fixed.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityNotFoundException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.web.bean.TreeBean;
import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.bizcore.web.utils.BuildTreeUtil;
import com.neusoft.neuiotms.dcam.fixed.converter.SpareTypeConverter;
import com.neusoft.neuiotms.dcam.fixed.dto.GoodsFileDTO;
import com.neusoft.neuiotms.dcam.fixed.dto.SpareTypeDTO;
import com.neusoft.neuiotms.dcam.fixed.model.AssetType;
import com.neusoft.neuiotms.dcam.fixed.model.SpareType;
import com.neusoft.neuiotms.dcam.fixed.repository.AssetTypeRepository;
import com.neusoft.neuiotms.dcam.fixed.repository.SpareTypeRepository;
import com.neusoft.neuiotms.dcam.fixed.service.GoodsFileService;
import com.neusoft.neuiotms.dcam.fixed.service.SpareTypeService;

@Service
public class SpareTypeServiceImpl implements SpareTypeService {

    @Autowired
    private SpareTypeConverter spareTypeConverter;

    @Autowired
    private SpareTypeRepository spareTypeRepository;

    @Autowired
    private AssetTypeRepository assetTypeRepository;

    @Autowired
    private GoodsFileService stockFileService;

    @Override
    public SpareTypeDTO create(final SpareTypeDTO dto) {

        final AssetType assetType = this.assetTypeRepository.findByCode(dto.getCode());
        if (assetType != null) {
            throw new UnitedException("分类编码已存在", new Object[] {});
        }

        final SpareType spareType = this.spareTypeRepository.findByCode(dto.getCode());
        if (spareType != null) {
            throw new UnitedException("分类编码已存在", new Object[] {});
        }

        final SpareType model = this.spareTypeConverter.toModel(dto);
        this.spareTypeRepository.save(model);
        return this.spareTypeConverter.toDTO(model);
    }

    @Override
    public void delete(final Long id) {
        final SpareType model;
        try {
            model = this.spareTypeRepository.getOne(id);
        } catch (final EmptyResultDataAccessException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        final List<GoodsFileDTO> stockFileDTOS = this.stockFileService.findBySpareType(model);
        if ((stockFileDTOS != null) && !stockFileDTOS.isEmpty()) {
            throw new UnitedException("该分类下已有货品，请先删除货品", new Object[] {id });
        }

        try {
            this.spareTypeRepository.deleteById(id);
        } catch (final EmptyResultDataAccessException e) {
            throw new UnitedException("此分类已经存在于业务中,不能删除", new Object[] {id });
        }
    }

    @Override
    public SpareTypeDTO update(final Long id, final SpareTypeDTO dto) {
        final AssetType assetType = this.assetTypeRepository.findByCode(dto.getCode());
        if (assetType != null) {
            throw new UnitedException("分类编码已存在", new Object[] {});
        }

        final SpareType spareType = this.spareTypeRepository.findByCode(dto.getCode());
        if ((spareType != null) && (spareType.getId() != id)) {
            throw new UnitedException("分类编码已存在", new Object[] {});
        }

        SpareType model;
        try {
            model = this.spareTypeRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        dto.setId(model.getId());
        model = this.spareTypeConverter.toModel(dto);
        this.spareTypeRepository.save(model);

        return this.spareTypeConverter.toDTO(model);
    }

    @Override
    public List<SpareTypeDTO> findAll() {
        final List<SpareType> models = this.spareTypeRepository.findAll();
        return this.spareTypeConverter.toListDTO(models);
    }

    @Override
    public SpareTypeDTO details(final Long id) {
        final SpareType model;
        try {
            model = this.spareTypeRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        return this.spareTypeConverter.toDTO(model);
    }

    @Override
    public Page<SpareTypeDTO> search(final Pageable pageable, final Searchable searchable) {
        final Page<SpareType> result = this.spareTypeRepository.search(pageable, searchable);
        return this.spareTypeConverter.toPageDTO(result);
    }

    @Override
    public List<TreeBean> tree() {
        final List<TreeBean> tree = new ArrayList<>();

        final List<SpareType> spareType = this.spareTypeRepository.findAll();
        spareType.forEach(type -> {
            final TreeBean bean = new TreeBean();
            bean.setCode(type.getCode());
            bean.setTitle(type.getName());
            final Map<String, Object> attr = new HashMap<>();
            attr.put("id", type.getCode());
            attr.put("parentId", type.getParent() == null ? "-1" : type.getParent().getCode());
            bean.setAttr(attr);
            tree.add(bean);
        });

        return new BuildTreeUtil(tree).buildTree();
    }

}
